#include <iostream>
#include <string>
#include <memory>
#include <cstring>
#include <memory.h>
using namespace std;

class String
{
private:
    char *str_{nullptr};
    int size_{0};

public:
    String() {};

    // 拷贝构造函数
    String(const String &str)
    {

        size_ = str.size_;
        str_ = new char[size_ + 1];

        memccpy(str_, str.str_, 1, size_ + 1);
    };

    // 移动构造函数
    String(String &&str)
    {
        // 管理原对象的堆空间
        str_ = str.str_;
        size_ = str.size_;

        // 清空原对象，原对象不再管理之前的空间
        str.str_ = nullptr;
        str.size_ = 0;
    };

    String(const char *str = "")
    {
        if (str[0] == 0)
            return;

        size_ = strlen(str);
        str_ = new char[size_ + 1];

        memccpy(str_, str, 1, size_ + 1);
    }

    ~String()
    {
        std::cout << "Drop String: " << size_ << std::endl;
        Clear();
    };

    void Clear()
    {
        if (str_)
        {
            delete[] str_;
            str_ = nullptr;
            size_ = 0;
        }
    }

    const char *c_str()
    {
        if (str_)
            return str_;
        return "";
    }

    size_t size()
    {
        return size_;
    }

    // 重载 赋值操作符
    String &operator=(const char *str)
    {

        // 对象本身 直接返回
        if (this->str_ == str)
        {
            return *this;
        }

        Clear();

        if (str == nullptr)
        {
            return *this;
        }

        auto len = strlen(str);
        if (len != 0)
        {
            size_ = len;
            str_ = new char[size_ + 1];

            memccpy(str_, str, 1, size_ + 1);
        }
        return *this;
    }

    // 重载 赋值操作符
    String &operator=(const String &str)
    {

        // 对象本身 直接返回
        if (this == &str)
        {
            return *this;
        }

        Clear();

        if (str.size_ != 0)
        {
            size_ = str.size_;
            str_ = new char[size_ + 1];

            memccpy(str_, str.str_, 1, size_ + 1);
        }
        return *this;
    }

    // 重载 赋值操作符
    String &operator=(String &&str)
    {
        // 对象本身 直接返回
        if (this == &str)
        {
            return *this;
        }

        Clear();

        if (str.size_ != 0)
        {
            // 管理原对象的堆空间
            str_ = str.str_;
            size_ = str.size_;

            // 清空原对象，原对象不再管理之前的空间
            delete str.str_;
            str.str_ = nullptr;
            str.size_ = 0;
        }
        return *this;
    }
};

void TestString(String s)
{
    std::cout << "TestString : " << s.c_str() << std::endl;
}

void TestStringRef(String &s)
{
    std::cout << "TestStringRef : " << s.c_str() << std::endl;
}

int main(int argc, char const *argv[])
{
    String str1("hello");
    std::cout << "Test String: " << str1.c_str() << std::endl;
    TestString(std::move(str1));
    str1 = "test operator= string";
    TestStringRef(str1);

    auto s = String("aaa");

    std::cout << "String: " << s.c_str() << std::endl;
    str1 = std::move(s);
    std::cout << "Test String: " << str1.c_str() << std::endl;
    return 0;
}
